#include "common/common.h"
#include "core/TCFixedString.h"
#include "string/stringoutput.h"
#include "testlibpilo.h"

using namespace PILO::Core::String;

INT32 caseStringTrimRight1(void * param);
INT32 caseStringTrimRight2(void * param);
INT32 caseStringTrimRight3(void * param);
INT32 caseStringTrimRight4(void * param);
INT32 caseStringTrimRight5(void * param);
INT32 caseStringTrimRight6(void * param);
INT32 caseStringTrimLeft1(void * param);
INT32 caseStringTrimLeft2(void * param);
INT32 caseStringTrimLeft3(void * param);
INT32 caseStringTrimLeft4(void * param);
INT32 caseStringTrimLeft5(void * param);
INT32 caseStringTrimLeft6(void * param);
INT32 caseStringTrim1(void * param);
INT32 caseStringTrim2(void * param);
INT32 caseStringTrim3(void * param);
INT32 caseStringTrim4(void * param);
INT32 caseStringTrim5(void * param);
INT32 caseStringTrim6(void * param);
INT32 caseStringAppendString1(void * param);
INT32 caseStringAppendString2(void * param);
INT32 caseStringAppendString_F1(void * param);
INT32 caseStringAppendString_F2(void * param);
INT32 caseStringAppend_int_A(void * param);
INT32 caseStringAppend_int_W(void * param);
INT32 caseStringAppend_float_A(void * param);
INT32 caseStringAppend_float_W(void * param);


static case_testing_t g_cases[] = {
	{1,  "StringTrimRight: with char,normal                 ",           0,caseStringTrimRight1, -1},
	{2,  "StringTrimRight: with char none space             ",           0,caseStringTrimRight2, -1},
	{3,  "StringTrimRight: with char all spaces             ",           0,caseStringTrimRight3, -1},
	{4,  "StringTrimRight: with wchar,normal                ",           0,caseStringTrimRight4, -1},
	{5,  "StringTrimRight: with wchar none space            ",           0,caseStringTrimRight5, -1},
	{6,  "StringTrimRight: with wchar all spaces            ",           0,caseStringTrimRight6, -1},

	{7,  "StringTrimLeft: with char, normal                 ",           0,caseStringTrimLeft1, -1},
	{8,  "StringTrimLeft: with char none space              ",           0,caseStringTrimLeft2, -1},
	{9,  "StringTrimLeft: with char all spaces              ",           0,caseStringTrimLeft3, -1},
	{10, "StringTrimLeft: with char, normal                 ",           0,caseStringTrimLeft4, -1},
	{11, "StringTrimLeft: with char none space              ",           0,caseStringTrimLeft5, -1},
	{12, "StringTrimLeft: with char all spaces              ",           0,caseStringTrimLeft6, -1},
	{13, "StringTrim: with char, normal                     ",           0,caseStringTrim1, -1},
	{14, "StringTrim: with char none space                  ",           0,caseStringTrim2, -1},
	{15, "StringTrim: with char all spaces                  ",           0,caseStringTrim3, -1},
	{16, "StringTrim: with char, normal                     ",           0,caseStringTrim4, -1},
	{17, "StringTrim: with char none space                  ",           0,caseStringTrim5, -1},
	{18, "StringTrim: with char all spaces                  ",           0,caseStringTrim6, -1},

	{19, "StringAppendString1: with char,by string          ",           0,caseStringAppendString1,-1},
	{20, "StringAppendString2: with wchar,by string         ",           0,caseStringAppendString2,-1},
	{21, "StringAppendString: with char,fail case           ",           0,caseStringAppendString_F1,-1},
	{22, "StringAppendString: with char,fail case           ",           0,caseStringAppendString_F2,-1},

	{23, "StringAppend: addint with char                    ",           0,caseStringAppend_int_A,-1},
	{24, "StringAppend: addint with char                    ",           0,caseStringAppend_int_W,-1},
	{25, "StringAppend: addfloat with wchar                 ",           0,caseStringAppend_float_A,-1},
	{26, "StringAppend: addfloat with wchar                 ",           0,caseStringAppend_float_W,-1},



};

static INT32 g_id = 0;

INT32 test_stringmanipulations_Functional(INT32 id, int breakOnErrorOccured)
{
	g_id = id;

	FormatOutputToConsole("Testing Part_%d <stringmanipulations.h/cpp>\n", id);
	int i=0;
	for (i=0; i<MCF_COUNT_OF(g_cases); i++) {
		case_testing_t * caseParam = &g_cases[i];
		ASSERT(caseParam != NULL);
		FormatOutputToConsole(" #[%03d.%03d]: Testing %s",g_id, caseParam->ct_id, caseParam->ct_decription);

		caseParam->ct_result = caseParam->ct_function(static_cast<case_testing_t *>(caseParam));
		if (caseParam->ct_result == 0) { //ok 
			FormatOutputToConsole("[PASSED]\n");
		} else {
			FormatOutputToConsole("[FAILED:%d]\n",caseParam->ct_result);
			if (breakOnErrorOccured) {
				ASSERT(false);
			}
		}
	}

	
	FormatOutputToConsole("Result of Part_%d <stringmanipulations.h/cpp> total %d,   failed %d\n\n",id, MCF_COUNT_OF(g_cases), failedOFCases(g_cases,MCF_COUNT_OF(g_cases) ));
	return 0;
}

// all cases defined here
INT32 caseStringTrimRight1(void * )
{
	char str1[] = "       MAPIXXX         ";
	int_r ret = StringTrimRight(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen) || (StringCompare(str1, "       MAPIXXX"))) {
		return -1;
	}

	return 0;
}

INT32 caseStringTrimRight2(void * )
{
	char str1[] = "abcdMAPIXXX1234";
	int_r ret = StringTrimRight(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen) || (StringCompare(str1, "abcdMAPIXXX1234"))) {
		return -1;
	}

	return 0;
}

INT32 caseStringTrimRight3(void * )
{
	char str1[] = "							";
	int_r ret = StringTrimRight(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen) || (ret != 0)) {
		return -1;
	}

	return 0;
}

INT32 caseStringTrimRight4(void * )
{
	wchar_t str1[] = L"       MAPIXXX         ";
	int_r ret = StringTrimRight(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen) || (StringCompare(str1, L"       MAPIXXX")))  {
		return -1;
	}

	return 0;
}

INT32 caseStringTrimRight5(void * )
{
	wchar_t str1[] = L"abcdMAPIXXX1234";
	int_r ret = StringTrimRight(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen) || (StringCompare(str1, L"abcdMAPIXXX1234")))  {
		return -1;
	}

	return 0;
}

INT32 caseStringTrimRight6(void * )
{
	wchar_t str1[] = L"							";
	int_r ret = StringTrimRight(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen)||(ret != 0)) {
		return -1;
	}

	return 0;
}

INT32 caseStringTrimLeft1(void * )
{
	char str1[] = "       MAPIXXX         ";
	int_r ret = StringTrimLeft(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen) || (StringCompare(str1, "MAPIXXX         ")))  {
		return -1;
	}

	return 0;
}

INT32 caseStringTrimLeft2(void * )
{
	char str1[] = "MAPIXXX";
	int_r ret = StringTrimLeft(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen) || (StringCompare(str1, "MAPIXXX")))  {
		return -1;
	}

	return 0;
}

INT32 caseStringTrimLeft3(void * )
{
	char str1[] = "					";
	int_r ret = StringTrimLeft(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen)||(ret != 0))  {
		return -1;
	}

	return 0;
}

INT32 caseStringTrimLeft4(void * )
{
	wchar_t str1[] = L"       MAPIXXX         ";
	int_r ret = StringTrimLeft(str1);
	int_r checkLen = StringLength(str1);

	if ((ret != checkLen) || (StringCompare(str1, L"MAPIXXX         "))) {
		return -1;
	}


	return 0;
}

INT32 caseStringTrimLeft5(void * )
{
	wchar_t str1[] = L"MAPIXXX";
	int_r ret = StringTrimLeft(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen) || (StringCompare(str1, L"MAPIXXX")))  {
		return -1;
	}

	return 0;
}

INT32 caseStringTrimLeft6(void * )
{
	wchar_t str1[] = L"					";
	int_r ret = StringTrimLeft(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen)||(ret != 0)) {
		return -1;
	}

	return 0;
}


INT32 caseStringTrim1(void * )
{
	char str1[] = "       MAPIXXX         ";
	int_r ret = StringTrim(str1);
	int_r checkLen = StringLength(str1);
	if  ((ret != checkLen) || (StringCompare(str1, "MAPIXXX"))){
		return -1;
	}

	return 0;
}

INT32 caseStringTrim2(void * )
{
	char str1[] = "MAPIXXX";
	int_r ret = StringTrim(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen) || (StringCompare(str1, "MAPIXXX"))) {
		return -1;
	}

	return 0;
}

INT32 caseStringTrim3(void * )
{
	char str1[] = "					";
	int_r ret = StringTrim(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen)||(ret != 0)) {
		return -1;
	}

	return 0;
}

INT32 caseStringTrim4(void * )
{
	wchar_t str1[] = L"       MAPIXXX         ";
	int_r ret = StringTrim(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen) || (StringCompare(str1, L"MAPIXXX"))) {
		return -1;
	}

	return 0;
}

INT32 caseStringTrim5(void * )
{
	wchar_t str1[] = L"MAPIXXX";
	int_r ret = StringTrim(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen) || (StringCompare(str1, L"MAPIXXX")))  {
		return -1;
	}

	return 0;
}

INT32 caseStringTrim6(void * )
{
	wchar_t str1[] = L"					";
	int_r ret = StringTrim(str1);
	int_r checkLen = StringLength(str1);
	if ((ret != checkLen)||(ret != 0)) {
		return -1;
	}

	return 0;
}

INT32 caseStringAppendString1(void * )
{
	char str1[17];

	StringCopy(str1,MCF_COUNT_OF(str1), "0123456789");

	int_r testLen =StringAppendString(str1, 10, 16, "abcdef",6);
	const char *str1c = "0123456789abcde";
	int_r checkLen = StringLength(str1c);
	if ((testLen != checkLen) || StringCompare(str1, str1c)) {
		return -1;
	}

	StringCopy(str1,MCF_COUNT_OF(str1), "0123456789");
	testLen =StringAppendString(str1, 10, 17, "abcdef",6);
	str1c = "0123456789abcdef";
	checkLen = StringLength(str1c);
	if ((testLen != checkLen) || StringCompare(str1, str1c)) {
		return -1;
	}

	StringCopy(str1,MCF_COUNT_OF(str1), "0123456789");
	testLen =StringAppendString(str1, MC_INVALID_SIZE, MC_INVALID_SIZE, "abcdef",MC_INVALID_SIZE);
	str1c = "0123456789abcdef";
	checkLen = StringLength(str1c);
	if ((testLen != checkLen) || StringCompare(str1, str1c)) {
		return -1;
	}


	return 0;
}

INT32 caseStringAppendString2(void * )
{
	wchar_t str1[17];
	StringCopy(str1,MCF_COUNT_OF(str1), L"0123456789");

	int_r testLen =StringAppendString(str1, 10, 16, L"abcdef",6);
	const wchar_t *str1c = L"0123456789abcde";
	int_r checkLen = StringLength(str1c);
	if ((testLen != checkLen) || StringCompare(str1, str1c)) {
		return -1;
	}

	StringCopy(str1,MCF_COUNT_OF(str1), L"0123456789");
	testLen =StringAppendString(str1, 10, 17, L"abcdef",6);
	str1c = L"0123456789abcdef";
	checkLen = StringLength(str1c);
	if ((testLen != checkLen) || StringCompare(str1, str1c)) {
		return -1;
	}

	StringCopy(str1,MCF_COUNT_OF(str1), L"0123456789");
	testLen =StringAppendString(str1, MC_INVALID_SIZE, MC_INVALID_SIZE, L"abcdef",MC_INVALID_SIZE);
	str1c = L"0123456789abcdef";
	checkLen = StringLength(str1c);
	if ((testLen != checkLen) || StringCompare(str1, str1c)) {
		return -1;
	}

	return 0;
}

INT32 caseStringAppendString_F1(void * )
{
	int_r ret;

	ret =  StringAppendString(MC_NULLPTR_OF_(char*), 12, 32, "abcdef", 0);
	if (ret != -1) {
		return -1;
	}

	char str1[32];
	str1[0] = 0;
	ret =  StringAppendString(str1, MC_INVALID_SIZE, 32, "abcdef", MC_INVALID_SIZE);
	if ((ret != 6) || (StringCompare(str1, "abcdef"))) {
		return -1;
	}

	char str2[]="0123456789";
	ret =  StringAppendString(str2, MC_INVALID_SIZE, 32, "", MC_INVALID_SIZE);
	if ((ret != 10) || (StringCompare(str2, "0123456789"))) {
		return -1;
	}

	return 0;
}

INT32 caseStringAppendString_F2(void * )
{
	int_r ret;

	ret =  StringAppendString(MC_NULLPTR_OF_(wchar_t*), 12, 32, L"abcdef", MC_INVALID_SIZE);
	if (ret != -1) {
		return -1;
	}

	wchar_t str1[32];
	str1[0] = 0;
	ret =  StringAppendString(str1, MC_INVALID_SIZE, 32, L"abcdef", MC_INVALID_SIZE);
	if ((ret != 6) || (StringCompare(str1, L"abcdef"))) {
		return -1;
	}

	wchar_t str2[]=L"0123456789";
	ret =  StringAppendString(str2, MC_INVALID_SIZE, 32, L"", MC_INVALID_SIZE);
	if ((ret != 10) || (StringCompare(str2, L"0123456789"))) {
		return -1;
	}

	return 0;
}

INT32 caseStringAppend_int_A(void * )
{
	char str[]="abcdefghijklmnxxxxxxxxxxxxxxxxx";
	INT8 i1 = -18;
	int_r retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, "%d", i1);
	if ((retLen != 7) || (StringCompare(str, "abcd-18"))) {
		return -11;
	}

	INT16 i2 = -25530;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, "%d", i2);
	if ((retLen != 10) || (StringCompare(str, "abcd-25530"))) {
		return -12;
	}

	INT32 i4 = -65536;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, "%d", i4);
	if ((retLen != 10) || (StringCompare(str, "abcd-65536"))) {
		return -14;
	}

	INT64 i8 = -17777777777777LL;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, "%lld", i8);
	if ((retLen != 19) || (StringCompare(str, "abcd-17777777777777"))) {
		return -18;
	}


	UINT8 u1 = 18;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, "%u", u1);
	if ((retLen != 6) || (StringCompare(str, "abcd18"))) {
		return -1;
	}

	UINT16 u2 = 65530;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, "%u", u2);
	if ((retLen != 9) || (StringCompare(str, "abcd65530"))) {
		return -2;
	}

	UINT32 u4 = 1000000009;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, "%u", u4);
	if ((retLen != 14) || (StringCompare(str, "abcd1000000009"))) {
		return -4;
	}

	UINT64 u8 = 17777777777777LL;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, "%llu", u8);
	if ((retLen != 18) || (StringCompare(str, "abcd17777777777777"))) {
		return -8;
	}

	return 0;
}

INT32 caseStringAppend_int_W(void * )
{
	wchar_t str[]=L"abcdefghijklmnxxxxxxxxxxxxxxxxx";
	INT8 i1 = -18;
	int_r retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, L"%d", i1);
	if ((retLen != 7) || (StringCompare(str, L"abcd-18"))) {
		return -11;
	}

	INT16 i2 = -25530;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, L"%d", i2);
	if ((retLen != 10) || (StringCompare(str, L"abcd-25530"))) {
		return -12;
	}

	INT32 i4 = -65536;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, L"%d", i4);
	if ((retLen != 10) || (StringCompare(str, L"abcd-65536"))) {
		return -14;
	}

	INT64 i8 = -17777777777777LL;
	retLen = StringAppendFormatted(str, 4,MC_INVALID_SIZE, L"%lld", i8);
	if ((retLen != 19) || (StringCompare(str, L"abcd-17777777777777"))) {
		return -18;
	}


	UINT8 u1 = 18;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, L"%u", u1);
	if ((retLen != 6) || (StringCompare(str, L"abcd18"))) {
		return -1;
	}

	UINT16 u2 = 65530;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, L"%u", u2);
	if ((retLen != 9) || (StringCompare(str, L"abcd65530"))) {
		return -2;
	}

	UINT32 u4 = 1000000009;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, L"%u", u4);
	if ((retLen != 14) || (StringCompare(str, L"abcd1000000009"))) {
		return -4;
	}

	UINT64 u8 = 17777777777777LL;
	retLen = StringAppendFormatted(str, 4, MC_INVALID_SIZE, L"%llu", u8);
	if ((retLen != 18) || (StringCompare(str, L"abcd17777777777777"))) {
		return -8;
	}

	return 0;
}


INT32 caseStringAppend_float_A(void * )
{
	char str[256];
	float f1 = -3.14159f;
	int_r baseLen = FormatOutputToString(str, 256, "The number:");
	int_r retLen = StringAppendFormatted(str, baseLen, 256, "%.5f", f1);
	if ((retLen != (baseLen+ 8)) || (StringCompare(str, "The number:-3.14159"))) {
		return -11;
	}

	double d1 = -3.14159265357;
	baseLen = FormatOutputToString(str, 256, "The number:");
	retLen = StringAppendFormatted(str, baseLen, 256, "%.11lf", d1);
	if ((retLen != (baseLen+ 14)) || (StringCompare(str, "The number:-3.14159265357"))) {
		return -12;
	}

	long double ld1 = -2.718281828459771;
	baseLen = FormatOutputToString(str, 256, "The number:");
	retLen = StringAppendFormatted(str, baseLen, 256, "%.15Lf", ld1);
	if ((retLen != (baseLen+ 18)) || (StringCompare(str, "The number:-2.718281828459771"))) {
		return -13;
	}
	

	return 0;
}


INT32 caseStringAppend_float_W(void * )
{
	wchar_t str[256];
	float f1 = -3.14159f;
	int_r baseLen = FormatOutputToString(str, 256, L"The number:");
	int_r retLen = StringAppendFormatted(str, baseLen, 256, L"%.5f", f1);
	if ((retLen != (baseLen+ 8)) || (StringCompare(str, L"The number:-3.14159"))) {
		return -11;
	}

	double d1 = -3.14159265357;
	baseLen = FormatOutputToString(str, 256, L"The number:");
	retLen = StringAppendFormatted(str, baseLen, 256, L"%.11lf", d1);
	if ((retLen != (baseLen+ 14)) || (StringCompare(str, L"The number:-3.14159265357"))) {
		return -12;
	}

	long double ld1 = -2.718281828459771;
	baseLen = FormatOutputToString(str, 256, L"The number:");
	retLen = StringAppendFormatted(str, baseLen, 256, L"%.15Lf", ld1);
	if ((retLen != (baseLen+ 18)) || (StringCompare(str, L"The number:-2.718281828459771"))) {
		return -13;
	}
	

	return 0;
}
